﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebChat.Models;
using System.Text.RegularExpressions;
namespace WebChat.Controllers
{
    public class AdminController : Controller
    {

        Regex input = new Regex("^[a-zA-Z0-9]{1,25}$"); //Validering av input
        Regex telefonnr = new Regex("^[0-9]{1,20}$");
        private ChannelRepository channelRep; //instans av Channel sitt Repository
        private UserRepository userRep; //instans av User sitt Repository
        private Permitted_user user; //en tilatt bruker, brukes i mange metoder
        private MessageRepository messageRep;
        private MessageFormViewModel view; //Meldingenes ViewModel
        Guid adminGuid;
        Guid userGuid;
        /// <summary>
        /// Konstruktør som oppretter de forskjellige repositoriene slik at 
        /// kontrolleren kan benytte seg av disse
        /// </summary>
        public AdminController()
        {
            messageRep = new MessageRepository();
            userRep = new UserRepository();
            channelRep = new ChannelRepository();
            adminGuid = new Guid("44e761d1-b87a-40b2-ac76-2910023069f6");
            userGuid = new Guid("45e761d1-b87a-40b2-ac76-2910123069f6");
        }
        /// <summary>
        /// Returnerer view for admin-menyen
        /// </summary>
        /// <param name="_usr"></param>
        /// <param name="_chtr"></param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult Index()
        {
            return View("Index");
        }
        /// <summary>
        /// returnerer view med brukere og handlinger for disse
        /// </summary>
        /// <returns></returns>
        #region Users
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult ListUsers()
        {
            Guid userId = userRep.getUserId(User.Identity.Name);
            List<aspnet_User> users = userRep.showOtherUsers(userId).ToList();
            return View(users);
        }
        /// <summary>
        /// returnerer detaljene til aktuell bruker
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult DetailsUsers(Guid id)
        {
            aspnet_User user = userRep.showUser(id);
            if (user == null)
                return View("NotFound");
            return View(user);
        }
        /// <summary>
        /// returnerer lovlige instiller for aktuell bruker
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult EditUsers(Guid id)
        {
            aspnet_User user = userRep.showUser(id);

            if (user == null)
                return View("NotFound");
            aspnet_UsersInRole usrInRole = userRep.getUserRoles(user);
            return View(user);
        }
        /// <summary>
        /// POST: /User/Edit/id
        /// Sender inn endre skjemaet
        /// </summary>
        /// <param name="id">Brukerens id</param>
        /// <param name="collection"></param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult EditUsers(Guid id,FormCollection collection)
        {
            Image image = new Image();
            HttpPostedFileBase file;

            try
            {
                aspnet_User User = userRep.showUser(id);
                UpdateModel(User);
                if (User.MobilePhoneNumber != null && !telefonnr.IsMatch(User.MobilePhoneNumber))
                {
                    ModelState.AddModelError("MobilePhoneNumber", "Dette feltet kan ha maks 20 tegn og må bestå av bare tall");
                    return View(User);
                }
                bool adm = User.Admin;
                User.Admin = adm;
                aspnet_UsersInRole usrInRole = userRep.getUserRoles(User);
                int imgId = User.imageId;

                if (usrInRole == null)
                {
                    usrInRole = new aspnet_UsersInRole();
                    if (adm == true)
                    {
                        usrInRole.RoleId = adminGuid;
                        usrInRole.UserId = User.UserId;
                        userRep.addRole(usrInRole);
                    }
                }
                else
                {
                    if (adm == true)
                    {
                        userRep.removeRole(usrInRole);
                        usrInRole = new aspnet_UsersInRole();
                        usrInRole.RoleId = adminGuid;
                        usrInRole.UserId = User.UserId;
                        userRep.addRole(usrInRole);
                    }
                    else
                    {
                        userRep.removeRole(usrInRole);
                    }
                }
                file = Request.Files[0];
                //Logikk for å få bilde inn i databasen
                
                if (file.ContentLength > 0)
                {
                    if (file.ContentLength > 1000000)
                    {
                        ModelState.AddModelError("imageId", "Filen er for stor.");
                        return View(User);
                    }
                    if (file.ContentType != "image/jpeg" && file.ContentType != "image/png" && file.ContentType != "image/gif")
                    {
                        ModelState.AddModelError("imageId", "Feil filtype. Støtter .jpg, .png og .gif");
                        return View(User);
                    }
                    image.imageName = file.FileName;
                    image.imageSize = file.ContentLength;
                    image.imageType = file.ContentType;
                    byte[] theImage = new byte[file.ContentLength];
                    file.InputStream.Read(theImage, 0, (int)file.ContentLength);
                    image.image1 = theImage;
                    User.imageId = messageRep.addImage(image);
                }

                userRep.updateUser(User);
                return RedirectToAction("DetailsUsers/" + User.UserId);
            }
            catch (Exception e)
            {
                return View("Error");
            }
        }
        /// <summary>
        /// GET: /User/Delete/id
        /// Lar deg slette en bruker
        /// </summary>
        /// <param name="id">Brukerens id</param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult DeleteUsers(Guid id)
        {
            aspnet_User user = userRep.showUser(id);
            List<Chatroom> chat = channelRep.showAllYourChatrooms(user.UserId);
            if (chat != null)
            {
                foreach (Chatroom u in chat)
                {
                    u.OwnerId = userRep.getUserId(User.Identity.Name);
                    channelRep.updateChannel(u);
                    DeleteChatrooms(u.Id);
                }
            }
            if (User == null)
                return View("NotFound");
            userRep.deleteUser(user);
            return RedirectToAction("ListUsers");
        }
        #endregion
        #region Messages
        /// <summary>
        /// Returnerer alle beskjeder 
        /// </summary>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult ListMessages()
        {
            List<Message> messages = messageRep.showAllMessages().ToList();
            foreach (Message m in messages)
            {
                m.name = userRep.getUserName(m.AuthorId);
                if (m.name == null)
                    m.name = "Bruker slettet";
            }
            return View(messages);
        }
        [HttpPost]
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult ListMessages(FormCollection form)
        {
            string input = form["fname"];
            List<Message> messages = messageRep.showMatchMessages(input).ToList();
            foreach (Message m in messages)
            {
                m.name = userRep.getUserName(m.AuthorId);
                if (m.name == null)
                    m.name = "Bruker slettet";
            }
            return View(messages);
        }
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult ListMessagesRoom(int id)
        {
            List<Message> messages = messageRep.showChatroomMessages(id).ToList();
            foreach (Message m in messages)
            {
                m.name = userRep.getUserName(m.AuthorId);
                if (m.name == null)
                    m.name = "Bruker slettet";
            }
            return View(messages);
        }

        /// <summary>
        /// returnerer detaljer over valgt melding
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult DetailsMessages(int id)
        {
            Message Message = messageRep.showMessage(id);
            Message.name = userRep.getUserName(Message.AuthorId);
            if (Message.imageId != null)
            {
                Message.imageType = messageRep.getFile(Message.imageId).imageType;
                Message.imageName = messageRep.getFile(Message.imageId).imageName;
                Message.imageSize = messageRep.getFile(Message.imageId).imageSize;
            }
            if (Message == null)
                return View("NotFound");
            return View(Message);
        }

        /// <summary>
        /// Post: /Message/Delete/id
        /// Oppdaterer databasen
        /// </summary>
        /// <param name="id">beskjed id</param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult DeleteMessages(int id)
        {
            try
            {
                // TODO: Add delete logic here
                Message Message = messageRep.showMessage(id);
                if (Message == null)
                    return View("NotFound");
                messageRep.deleteMessage(Message);
                return RedirectToAction("ListMessages");
            }
            catch
            {
                return View();
            }
        }

        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult DeleteRoomMessages(int id, int chatId)
        {
            try
            {
                // TODO: Add delete logic here
                Message Message = messageRep.showMessage(id);
                if (Message == null)
                    return View("NotFound");
                messageRep.deleteMessage(Message);
                return RedirectToAction("ListMessagesRoom/" + chatId);
            }
            catch
            {
                return View();
            }
        }
        #endregion
        #region Chatroom
        /// <summary>
        /// Liste over alle chatrooms
        /// </summary>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult ListRooms()
        {
            List<Chatroom> chat = channelRep.showAllChatRooms().ToList();
            return View(chat);
        }
        /// <summary>
        /// Detaljer for valgt chatroom
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult DetailsRooms(int id)
        {
            Chatroom chat = channelRep.showChatroom(id);
            if (chat == null)
                return View("NotFound");
            return View(chat);
        }
        /// <summary>
        /// Viser et chatroom
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult Room(int id)
        {
            Chatroom channel = channelRep.showChatroom(id);
            user = userRep.showPermittedUser(userRep.getUserId(User.Identity.Name).ToString());
            List<Permitted_user> users = userRep.showUserWithChatroom(id);
            view = new MessageFormViewModel(id);
            if (channel == null) //Skjekker om rommet finnes
                return View("Notfound");
            if (user == null)
                return View("Error");
            foreach (Permitted_user u in users) //Skjekker om brukeren har tilgang til rommet eller om man eier det.
            {
                if (channel.IsPublic == "No" && u.UserId == user.UserId)
                    return View(view);
                else if (channel.OwnerId == (userRep.getOwner(channel).UserId))
                    return View(view);
            }
            if (channel.IsPublic == "Yes")
                return View(view);
            //Kommer man hit har det skjedd noe galt
            return View("Error");
        }
        /// <summary>
        /// GET: /Channel/Create
        /// returnerer ett skjema for å lage ett chatrom
        /// </summary>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult CreateChatrooms()
        {
            return View("CreateChatrooms", new ChannelFormViewModel(new Chatroom(), User.Identity.Name));
        }
        /// <summary>
        /// POST: /Channel/Create
        /// Sender inn skjema og legger til i databasen
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult CreateChatrooms(FormCollection collection)
        {
            try
            {
                Chatroom room = new Chatroom();
                List<Permitted_user> users = new List<Permitted_user>();
                user = new Permitted_user();
                //Logikk for å legge til ett nytt rom
                room.Date = System.DateTime.Now;
                room.OwnerId = userRep.getUserId(User.Identity.Name);
                UpdateModel(room, "room");
                if (room.Name == null) //Skjekker om man skriver inn romnavn
                {
                    ModelState.AddModelError("room.Name", "Dette feltet må fylles ut");
                    return View(new ChannelFormViewModel(room, User.Identity.Name));
                }
                if (!input.IsMatch(room.Name)) //Skjekker om rommet er i rett format
                {
                    ModelState.AddModelError("room.Name", "Navnet kan bare være av bokstaver og tall, samt 25 eller færre tegn.");
                    return View(new ChannelFormViewModel(room, User.Identity.Name));
                }
                channelRep.addChannel(room);
                string[] selectedValues;
                if (!(collection["Users"] == null)) //Henter en liste over brukerid, og skjekker om en er null
                {
                    selectedValues = collection["Users"].Split(',');
                    if (room.IsPublic == "No") //Hvis rommet er public er det ikke vits å ha tilatte brukere
                    {
                        foreach (string s in selectedValues) //For hver bruker du velger legger han dem til i databasen
                        {
                            user = new Permitted_user();
                            user.Chatroom = room.Id;
                            user.UserId = Guid.Parse(s);
                            userRep.addPermittedUsers(user);
                        }
                    }
                }
                //Om alt gikk bra sendes du til Channel/Index
                return RedirectToAction("Index");
            }
            catch
            {
                return View("DatabaseError"); //Sendes til ett error view
            }
        }
        /// <summary>
        /// GET: /Channel/Edit/id
        /// Sender deg til ett endre skjema
        /// </summary>
        /// <param name="id">Navn på rommet</param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult EditChatrooms(int id)
        {
            Chatroom channel = channelRep.showChatroom(id);
            List<Permitted_user> users;
            users = userRep.showUserWithChatroom(id); //Henter alle brukere som har tilgang til rommet
            return View(new ChannelFormViewModel(channel, users, User.Identity.Name));
        }
        /// <summary>
        /// POST: /Channel/Edit/id
        /// Sender inn endre skjemaet
        /// </summary>
        /// <param name="id">Navn på rommet</param>
        /// <param name="collection"></param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        [HttpPost]
        public ActionResult EditChatrooms(int id, FormCollection collection)
        {
            try
            {
                //Logikk for å endre ett rom
                Chatroom room = channelRep.showChatroom(id);
                UpdateModel(room, "room");
                List<Permitted_user> users = userRep.showUserWithChatroom(id);
                if (room.Name == null) //Skjekker om man har skrevet inn romnavn
                {
                    ModelState.AddModelError("room.Name", "Dette feltet må fylles ut");
                    return View(new ChannelFormViewModel(room, users, User.Identity.Name));
                }
                if (!input.IsMatch(room.Name)) //Skjekker om rommet er i rett format
                {
                    ModelState.AddModelError("room.Name", "Navnet kan bare være av bokstaver og tall, samt 25 eller færre tegn.");
                    return View(new ChannelFormViewModel(room, users, User.Identity.Name));
                }
                channelRep.updateChannel(room);
                //Samme logikk som i Create
                if (!(collection["Users"] == null))
                {
                    string[] selectedValues = collection["Users"].Split(',');
                    foreach (string s in selectedValues)
                    {
                        user = new Permitted_user();
                        user.Chatroom = room.Id;
                        user.UserId = Guid.Parse(s);
                        userRep.addPermittedUsers(user);
                    }
                }
                //Her legger han brukere du velger å fjerne fra rommet ditt i en liste
                //og så sletter dem fra databasen
                if (!(collection["CurrentUsers"] == null))
                {
                    string[] selectedCurrentUsers = collection["CurrentUsers"].Split(',');
                    foreach (string s in selectedCurrentUsers)
                    {
                        Permitted_user u = userRep.showPermittedUser(s);
                        userRep.deletePermittedUsers(u);
                        System.Threading.Thread.Sleep(100); // Fant ut at databasen ikke håndterte spørringene raskt nok, og ikke alle gikk gjennom hvær gang, så la inn en liten pause.
                    }
                }
                return RedirectToAction("ListRooms");
            }
            catch
            {
                return View("Error");
            }
        }
        /// <summary>
        /// GET: /Channel/Delete/id
        /// Lar deg slette rom
        /// </summary>
        /// <param name="id">Navn på rommet</param>
        /// <returns></returns>
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult DeleteChatrooms(int id)
        {
            Chatroom chat = channelRep.showChatroom(id);
            if (chat == null)
                return View("Notfound");
            chat.Active = "No";
            channelRep.updateChannel(chat);
            return RedirectToAction("ListRooms");
        }
        [Authorize]
        [Authorize(Roles = "Administrator")]
        public ActionResult ActivateChatrooms(int id)
        {
            Chatroom channel = channelRep.showChatroom(id);
            if (channel == null)
                return View("Notfound");
            Chatroom chat = channelRep.showChatroom(id);
            chat.Active = "Yes";
            channelRep.updateChannel(chat);
            return RedirectToAction("ListRooms");
        }
        #endregion
    }

}